"""
用户 CRUD 操作
"""
from typing import Optional, List
from tortoise.exceptions import DoesNotExist
from fastapi import HTTPException, status
from ..models.user import User, UserStatus
from ..schemas.user import UserCreate, UserUpdate
from ..core.security import get_password_hash, verify_password


class UserCRUD:
    """用户 CRUD 操作类"""

    @staticmethod
    async def create_user(user_data: UserCreate) -> User:
        """创建用户"""
        # 检查用户名是否已存在
        existing_user = await User.filter(job_number=user_data.job_number).first()
        if existing_user:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="工号已存在"
            )

        # 如果提供了role_id，检查角色是否存在
        if user_data.role_id:
            from ..models.role import Role
            role_exists = await Role.filter(role_id=user_data.role_id).exists()
            if not role_exists:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail=f"角色ID {user_data.role_id} 不存在"
                )

        # 创建新用户
        hashed_password = get_password_hash(user_data.password)
        
        # 根据是否提供 role_id 决定创建方式
        create_data = {
            "username": user_data.username,
            "job_number": user_data.job_number,
            "password": hashed_password,
            "phone_number": user_data.phone_number,
            "email": user_data.email
        }
        
        # 只有当 role_id 不为 None 时才设置
        if user_data.role_id is not None:
            create_data["role_id"] = user_data.role_id
            
        user = await User.create(**create_data)
        
        # 预加载角色信息（如果有角色）
        if getattr(user, 'role_id', None):
            await user.fetch_related('role')
        return user

    @staticmethod
    async def get_user_by_id(job_number: str) -> User:
        """根据 job_number 获取用户"""
        try:
            user = await User.get(job_number=job_number).prefetch_related('role')
            return user
        except DoesNotExist:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                # detail=f"用户 工号 {job_number} 不存在"
                detail=f"用户 工号 {job_number} 不存在"
            )

    @staticmethod
    async def get_user_by_job_number(job_number: str) -> Optional[User]:
        """根据工号获取用户"""
        return await User.filter(job_number=job_number).prefetch_related('role').first()

    @staticmethod
    async def get_user_by_username(username: str) -> Optional[User]:
        """根据用户名获取用户"""
        return await User.filter(username=username).prefetch_related('role').first()

    @staticmethod
    async def get_users(skip: int = 0, limit: int = 100) -> List[User]:
        """获取用户列表"""
        return await User.all().prefetch_related('role').offset(skip).limit(limit)

    @staticmethod
    async def get_users_count() -> int:
        """获取用户总数"""
        return await User.all().count()

    @staticmethod
    async def update_user(job_number: str, user_data: UserUpdate) -> User:
        """更新用户信息"""
        user = await UserCRUD.get_user_by_id(job_number=job_number)
        
        update_data = user_data.model_dump(exclude_unset=True)
        if update_data:
            await user.update_from_dict(update_data)
            await user.save()
            # 重新获取包含角色信息的用户
            await user.fetch_related('role')
        
        return user

    @staticmethod
    async def delete_user(job_number: str) -> bool:
        """删除用户"""
        user = await UserCRUD.get_user_by_id(job_number=job_number)
        await user.delete()
        return True

    @staticmethod
    async def authenticate_user(job_number: str, password: str) -> User:
        """验证用户登录"""
        user = await UserCRUD.get_user_by_job_number(job_number)
        if not user:
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="用户名或密码错误"
            )
        
        if not verify_password(password, user.password):
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="用户名或密码错误"
            )
        
        if user.status != UserStatus.ACTIVE:
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="用户账户已被禁用"
            )
        
        return user

    @staticmethod
    async def change_user_status(job_number: str, status: UserStatus) -> User:
        """修改用户状态"""
        user = await UserCRUD.get_user_by_id(job_number=job_number)
        user.status = status
        await user.save()
        await user.fetch_related('role')
        return user

    @staticmethod
    async def update_user_password_admin(job_number: str, password: str):
        """管理员修改用户密码"""
        user = await UserCRUD.get_user_by_id(job_number=job_number)
        user.password = get_password_hash(password)
        await user.save()
        return True


# 创建全局实例
user_crud = UserCRUD()